import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_page_flip/flutter_page_flip.dart';
import 'package:flutter_page_flip/src/page_container.dart';

void main() {
  group('PageFlip Performance Tests', () {
    testWidgets('Controller should use only 3 animation controllers',
        (WidgetTester tester) async {
      // 创建一个大页面数的控制器来测试优化效果
      const pageCount = 1000;

      final controller = PageFlipController(
        pageCount: pageCount,
        pageBuilder: (index) => Container(
          color: Colors.blue,
          child: Center(
            child: Text('Page $index'),
          ),
        ),
        config: const PageFlipConfig(),
      );

      // 创建一个简单的测试Widget
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: PageFlipWidget(
              controller: controller,
            ),
          ),
        ),
      );

      // 验证控制器只使用了3个动画控制器，而不是1000个
      // 这是通过检查容器管理器的容器数量来验证的
      expect(PageContainerManager.containerCount, equals(3));

      // 验证当前页面索引正确
      expect(controller.currentIndex, equals(0));

      // 验证页面总数正确
      expect(controller.pageCount, equals(pageCount));

      controller.dispose();
    });

    testWidgets('Page containers should be reused correctly',
        (WidgetTester tester) async {
      const pageCount = 10;

      final controller = PageFlipController(
        pageCount: pageCount,
        pageBuilder: (index) => Container(
          key: ValueKey('page_$index'),
          color: Colors.primaries[index % Colors.primaries.length],
          child: Center(
            child: Text('Page $index', style: const TextStyle(fontSize: 24)),
          ),
        ),
        config: const PageFlipConfig(),
      );

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: PageFlipWidget(
              controller: controller,
            ),
          ),
        ),
      );

      // 验证初始状态
      expect(controller.currentIndex, equals(0));

      // 验证容器映射
      final containerManager = controller.containerManager;

      // 容器0：前一页 (null，因为当前是第0页)
      expect(containerManager.getContainerPageIndex(0), isNull);

      // 容器1：当前页 (0)
      expect(containerManager.getContainerPageIndex(1), equals(0));

      // 容器2：下一页 (1)
      expect(containerManager.getContainerPageIndex(2), equals(1));

      // 模拟翻页到第1页
      await controller.goToPage(1, animate: false);
      await tester.pump();

      // 验证翻页后的容器映射
      expect(controller.currentIndex, equals(1));

      // 容器0：前一页 (0)
      expect(containerManager.getContainerPageIndex(0), equals(0));

      // 容器1：当前页 (1)
      expect(containerManager.getContainerPageIndex(1), equals(1));

      // 容器2：下一页 (2)
      expect(containerManager.getContainerPageIndex(2), equals(2));

      // 再翻页到第2页
      await controller.goToPage(2, animate: false);
      await tester.pump();

      // 验证翻页后的容器映射
      expect(controller.currentIndex, equals(2));

      // 容器0：前一页 (1)
      expect(containerManager.getContainerPageIndex(0), equals(1));

      // 容器1：当前页 (2)
      expect(containerManager.getContainerPageIndex(1), equals(2));

      // 容器2：下一页 (3)
      expect(containerManager.getContainerPageIndex(2), equals(3));

      controller.dispose();
    });

    testWidgets('Memory usage should be optimized with page containers',
        (WidgetTester tester) async {
      // 创建一个大页面数的控制器
      const pageCount = 500;
      int buildCount = 0;

      final controller = PageFlipController(
        pageCount: pageCount,
        pageBuilder: (index) {
          buildCount++;
          return Container(
            color: Colors.primaries[index % Colors.primaries.length],
            child: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text('Page $index', style: const TextStyle(fontSize: 24)),
                  Text('Build count: $buildCount',
                      style: const TextStyle(fontSize: 12)),
                ],
              ),
            ),
          );
        },
        config: const PageFlipConfig(),
      );

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: PageFlipWidget(
              controller: controller,
            ),
          ),
        ),
      );

      // 初始构建应该只构建3个页面（前一页、当前页、下一页）
      // 由于第0页没有前一页，所以只构建2个页面
      expect(buildCount, lessThanOrEqualTo(3));

      final initialBuildCount = buildCount;

      // 翻页几次，验证不会重复构建已经构建过的页面
      await controller.goToPage(1, animate: false);
      await tester.pump();

      await controller.goToPage(2, animate: false);
      await tester.pump();

      await controller.goToPage(3, animate: false);
      await tester.pump();

      // 由于页面容器复用，构建次数应该保持在合理范围内
      // 不应该每次翻页都重新构建所有页面
      expect(buildCount, lessThan(pageCount));

      // 验证构建次数增长是合理的（考虑到页面容器的更新机制）
      // 由于我们的实现会在页面索引变化时重新创建容器，构建次数会稍多一些
      expect(buildCount - initialBuildCount, lessThanOrEqualTo(15));

      controller.dispose();
    });

    testWidgets('Animation controllers should be limited to 3',
        (WidgetTester tester) async {
      const pageCount = 100;

      final controller = PageFlipController(
        pageCount: pageCount,
        pageBuilder: (index) => Container(
          child: Center(child: Text('Page $index')),
        ),
        config: const PageFlipConfig(),
      );

      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: PageFlipWidget(
              controller: controller,
            ),
          ),
        ),
      );

      // 验证动画控制器数量
      // 通过检查不同页面索引是否能获取到动画控制器来验证

      // 页面0应该能获取到动画控制器（映射到容器1）
      final controller0 = controller.getAnimationController(0);
      expect(controller0, isNotNull);

      // 页面1应该能获取到动画控制器（映射到容器2）
      final controller1 = controller.getAnimationController(1);
      expect(controller1, isNotNull);

      // 页面99应该也能获取到动画控制器（通过模运算映射）
      final controller99 = controller.getAnimationController(99);
      expect(controller99, isNotNull);

      // 验证动画控制器是通过模运算复用的
      // 页面0和页面3应该使用同一个动画控制器
      final controller3 = controller.getAnimationController(3);
      expect(controller0, equals(controller3));

      controller.dispose();
    });
  });
}
